home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / g_quake / quakecc.zip / QCC.H < prev    next >
C/C++ Source or Header  |  1996-07-25  |  14KB  |  435 lines

  1.  
  2. #include "cmdlib.h"
  3. #include <stdio.h>
  4. #include <setjmp.h>
  5.  
  6. #include "pr_comp.h"
  7.  
  8. /*
  9.  
  10. TODO:
  11.  
  12. "stopped at 10 errors"
  13.  
  14. other pointer types for models and clients?
  15.  
  16. compact string heap?
  17.  
  18. allways initialize all variables to something safe
  19.  
  20. the def->type->type arrangement is really silly.
  21.  
  22. return type checking
  23.  
  24. parm count type checking
  25.  
  26. immediate overflow checking
  27.  
  28. pass the first two parms in call->b and call->c
  29.  
  30. */
  31.  
  32. /*
  33.  
  34. comments
  35. --------
  36. // comments discard text until the end of line
  37. / *  * / comments discard all enclosed text (spaced out on this line because this documentation is in a regular C comment block, and typing them in normally causes a parse error)
  38.  
  39. code structure
  40. --------------
  41. A definition is:
  42.     <type> <name> [ = <immediate>] {, <name> [ = <immediate>] };
  43.  
  44.  
  45. types
  46. -----
  47. simple types: void, float, vector, string, or entity
  48.     float        width, height;
  49.     string        name;
  50.     entity        self, other;
  51.  
  52. vector types:
  53.     vector        org;    // also creates org_x, org_y, and org_z float defs
  54.     
  55.     
  56. A function type is specified as:     simpletype ( type name {,type name} )
  57. The names are ignored except when the function is initialized.    
  58.     void()        think;
  59.     entity()    FindTarget;
  60.     void(vector destination, float speed, void() callback)    SUB_CalcMove;
  61.     void(...)    dprint;        // variable argument builtin
  62.  
  63. A field type is specified as:  .type
  64.     .vector        origin;
  65.     .string        netname;
  66.     .void()        think, touch, use;
  67.     
  68.  
  69. names
  70. -----
  71. Names are a maximum of 64 characters, must begin with A-Z,a-z, or _, and can continue with those characters or 0-9.
  72.  
  73. There are two levels of scoping: global, and function.  The parameter list of a function and any vars declared inside a function with the "local" statement are only visible within that function, 
  74.  
  75.  
  76. immediates
  77. ----------
  78. Float immediates must begin with 0-9 or minus sign.  .5 is illegal.
  79.     
  80. A parsing ambiguity is present with negative constants. "a-5" will be parsed as "a", then "-5", causing an error.  Seperate the - from the digits with a space "a - 5" to get the proper behavior.
  81.     12
  82.     1.6
  83.     0.5
  84.     -100
  85.  
  86. Vector immediates are three float immediates enclosed in single quotes.
  87.     '0 0 0'
  88.     '20.5 -10 0.00001'
  89.     
  90. String immediates are characters enclosed in double quotes.  The string cannot contain explicit newlines, but the escape character \n can embed one.  The \" escape can be used to include a quote in the string.
  91.     "maps/jrwiz1.bsp"
  92.     "sound/nin/pain.wav"
  93.     "ouch!\n"
  94.  
  95. Code immediates are statements enclosed in {} braces.
  96. statement:
  97.     { <multiple statements> }
  98.     <expression>;
  99.     local <type> <name> [ = <immediate>] {, <name> [ = <immediate>] };
  100.     return <expression>;
  101.     if ( <expression> ) <statement> [ else <statement> ];
  102.     while ( <expression> ) <statement>;
  103.     do <statement> while ( <expression> );
  104.     <function name> ( <function parms> );
  105.     
  106. expression:
  107.     combiations of names and these operators with standard C precedence:
  108.     "&&", "||", "<=", ">=","==", "!=", "!", "*", "/", "-", "+", "=", ".", "<", ">", "&", "|"
  109.     Parenthesis can be used to alter order of operation.
  110.     The & and | operations perform integral bit ops on floats
  111.     
  112. A built in function immediate is a number sign followed by an integer.
  113.     #1
  114.     #12
  115.  
  116.  
  117. compilation
  118. -----------
  119. Source files are processed sequentially without dumping any state, so if a defs file is the first one processed, the definitions will be available to all other files.
  120.  
  121. The language is strongly typed and there are no casts.
  122.  
  123. Anything that is initialized is assumed to be constant, and will have immediates folded into it.  If you change the value, your program will malfunction.  All uninitialized globals will be saved to savegame files.
  124.  
  125. Functions cannot have more than eight parameters.
  126.  
  127. Error recovery during compilation is minimal.  It will skip to the next global definition, so you will never see more than one error at a time in a given function.  All compilation aborts after ten error messages.
  128.  
  129. Names can be defined multiple times until they are defined with an initialization, allowing functions to be prototyped before their definition.
  130.  
  131. void()    MyFunction;            // the prototype
  132.  
  133. void()    MyFunction =        // the initialization
  134. {
  135.     dprint ("we're here\n");
  136. };
  137.  
  138.  
  139. entities and fields
  140. -------------------
  141.  
  142.  
  143. execution
  144. ---------
  145. Code execution is initiated by C code in quake from two main places:  the timed think routines for periodic control, and the touch function when two objects impact each other.
  146.  
  147. There are three global variables that are set before beginning code execution:
  148.     entity    world;        // the server's world object, which holds all global
  149.                         // state for the server, like the deathmatch flags
  150.                         // and the body ques.
  151.     entity    self;        // the entity the function is executing for
  152.     entity    other;        // the other object in an impact, not used for thinks
  153.     float    time;        // the current game time.  Note that because the
  154.                         // entities in the world are simulated sequentially,
  155.                         // time is NOT strictly increasing.  An impact late
  156.                         // in one entity's time slice may set time higher
  157.                         // than the think function of the next entity. 
  158.                         // The difference is limited to 0.1 seconds.
  159. Execution is also caused by a few uncommon events, like the addition of a new client to an existing server.
  160.     
  161. There is a runnaway counter that stops a program if 100000 statements are executed, assuming it is in an infinite loop.
  162.  
  163. It is acceptable to change the system set global variables.  This is usually done to pose as another entity by changing self and calling a function.
  164.  
  165. The interpretation is fairly efficient, but it is still over an order of magnitude slower than compiled C code.  All time consuming operations should be made into built in functions.
  166.  
  167. A profile counter is kept for each function, and incremented for each interpreted instruction inside that function.  The "profile" console command in Quake will dump out the top 10 functions, then clear all the counters.  The "profile all" command will dump sorted stats for every function that has been executed.
  168.  
  169.  
  170. afunc ( 4, bfunc(1,2,3));
  171. will fail because there is a shared parameter marshaling area, which will cause the 1 from bfunc to overwrite the 4 allready placed in parm0.  When a function is called, it copies the parms from the globals into it's privately scoped variables, so there is no collision when calling another function.
  172.  
  173. total = factorial(3) + factorial(4);
  174. Will fail because the return value from functions is held in a single global area.  If this really gets on your nerves, tell me and I can work around it at a slight performance and space penalty by allocating a new register for the function call and copying it out.
  175.  
  176.  
  177. built in functions
  178. ------------------
  179. void(string text)    dprint;
  180. Prints the string to the server console.
  181.  
  182. void(entity client, string text)    cprint;
  183. Prints a message to a specific client.
  184.  
  185. void(string text)    bprint;
  186. Broadcast prints a message to all clients on the current server.
  187.  
  188. entity()    spawn;
  189. Returns a totally empty entity.  You can manually set everything up, or just set the origin and call one of the existing entity setup functions.
  190.  
  191. entity(entity start, .string field, string match) find;
  192. Searches the server entity list beginning at start, looking for an entity that has entity.field = match.  To start at the beginning of the list, pass world.  World is returned when the end of the list is reached.
  193.  
  194. <FIXME: define all the other functions...>
  195.  
  196.  
  197. gotchas
  198. -------
  199.  
  200. The && and || operators DO NOT EARLY OUT like C!
  201.  
  202. Don't confuse single quoted vectors with double quoted strings
  203.  
  204. The function declaration syntax takes a little getting used to.
  205.  
  206. Don't forget the ; after the trailing brace of a function initialization.
  207.  
  208. Don't forget the "local" before defining local variables.
  209.  
  210. There are no ++ / -- operators, or operate/assign operators.
  211.  
  212. */
  213.  
  214. //=============================================================================
  215.  
  216. // offsets are allways multiplied by 4 before using
  217. typedef int    gofs_t;                // offset in global data block
  218. typedef struct function_s function_t;
  219.  
  220. #define    MAX_PARMS    8
  221.  
  222. typedef struct type_s
  223. {
  224.     etype_t            type;
  225.     struct def_s    *def;        // a def that points to this type
  226.     struct type_s    *next;
  227. // function types are more complex
  228.     struct type_s    *aux_type;    // return type or field type
  229.     int                num_parms;    // -1 = variable args
  230.     struct type_s    *parm_types[MAX_PARMS];    // only [num_parms] allocated
  231. } type_t;
  232.  
  233. typedef struct def_s
  234. {
  235.     type_t        *type;
  236.     char        *name;
  237.     struct def_s    *next;
  238.     gofs_t        ofs;
  239.     struct def_s    *scope;        // function the var was defined in, or NULL
  240.     int            initialized;    // 1 when a declaration included "= immediate"
  241. } def_t;
  242.  
  243. //============================================================================
  244.  
  245. // pr_loc.h -- program local defs
  246.  
  247. #define    MAX_ERRORS        10
  248.  
  249. #define    MAX_NAME        64        // chars long
  250.  
  251. #define    MAX_REGS        16384
  252.  
  253. //=============================================================================
  254.  
  255. typedef union eval_s
  256. {
  257.     string_t            string;
  258.     float                _float;
  259.     float                vector[3];
  260.     func_t                function;
  261.     int                    _int;
  262.     union eval_s        *ptr;
  263. } eval_t;    
  264.  
  265. extern    int        type_size[8];
  266. extern    def_t    *def_for_type[8];
  267.  
  268. extern    type_t    type_void, type_string, type_float, type_vector, type_entity, type_field, type_function, type_pointer, type_floatfield;
  269.  
  270. extern    def_t    def_void, def_string, def_float, def_vector, def_entity, def_field, def_function, def_pointer;
  271.  
  272. struct function_s
  273. {
  274.     int                    builtin;    // if non 0, call an internal function
  275.     int                    code;        // first statement
  276.     char                *file;        // source file with definition
  277.     int                    file_line;
  278.     struct def_s        *def;
  279.     int                    parm_ofs[MAX_PARMS];    // allways contiguous, right?
  280. };
  281.  
  282.  
  283. //
  284. // output generated by prog parsing
  285. //
  286. typedef struct
  287. {
  288.     char        *memory;
  289.     int            max_memory;
  290.     int            current_memory;
  291.     type_t        *types;
  292.     
  293.     def_t        def_head;        // unused head of linked list
  294.     def_t        *def_tail;        // add new defs after this and move it
  295.     
  296.     int            size_fields;
  297. } pr_info_t;
  298.  
  299. extern    pr_info_t    pr;
  300.  
  301. typedef struct
  302. {
  303.     char        *name;
  304.     char        *opname;
  305.     float        priority;
  306.     boolean    right_associative;
  307.     def_t        *type_a, *type_b, *type_c;
  308. } opcode_t;
  309.  
  310. //============================================================================
  311.  
  312.  
  313. extern    opcode_t    pr_opcodes[99];        // sized by initialization
  314.  
  315. extern    boolean    pr_dumpasm;
  316.  
  317. extern    def_t        *pr_global_defs[MAX_REGS];    // to find def for a global variable
  318.  
  319. typedef enum {
  320. tt_eof,            // end of file reached
  321. tt_name,         // an alphanumeric name token
  322. tt_punct,         // code punctuation
  323. tt_immediate,    // string, float, vector
  324. } token_type_t;
  325.  
  326. extern    char        pr_token[2048];
  327. extern    token_type_t    pr_token_type;
  328. extern    type_t        *pr_immediate_type;
  329. extern    eval_t        pr_immediate;
  330.  
  331. void PR_PrintStatement (dstatement_t *s);
  332.  
  333. void PR_Lex (void);
  334. // reads the next token into pr_token and classifies its type
  335.  
  336. type_t *PR_ParseType (void);
  337. char *PR_ParseName (void);
  338.  
  339. boolean PR_Check (char *string);
  340. void PR_Expect (char *string);
  341. void PR_ParseError (char *error, ...);
  342.  
  343.  
  344. extern    jmp_buf        pr_parse_abort;        // longjump with this on parse error
  345. extern    int            pr_source_line;
  346. extern    char        *pr_file_p;
  347.  
  348. void *PR_Malloc (int size);
  349.  
  350.  
  351. #define    OFS_NULL        0
  352. #define    OFS_RETURN        1
  353. #define    OFS_PARM0        4        // leave 3 ofs for each parm to hold vectors
  354. #define    OFS_PARM1        7
  355. #define    OFS_PARM2        10
  356. #define    OFS_PARM3        13
  357. #define    OFS_PARM4        16
  358. #define    RESERVED_OFS    28
  359.  
  360.  
  361. extern    def_t    *pr_scope;
  362. extern    int        pr_error_count;
  363.  
  364. void PR_NewLine (void);
  365. def_t *PR_GetDef (type_t *type, char *name, def_t *scope, boolean allocate);
  366.  
  367. void PR_PrintDefs (void);
  368.  
  369. void PR_SkipToSemicolon (void);
  370.  
  371. extern    char        pr_parm_names[MAX_PARMS][MAX_NAME];
  372. extern    boolean    pr_trace;
  373.  
  374. #define    G_FLOAT(o) (pr_globals[o])
  375. #define    G_INT(o) (*(int *)&pr_globals[o])
  376. #define    G_VECTOR(o) (&pr_globals[o])
  377. #define    G_STRING(o) (strings + *(string_t *)&pr_globals[o])
  378. #define    G_FUNCTION(o) (*(func_t *)&pr_globals[o])
  379.  
  380. char *PR_ValueString (etype_t type, void *val);
  381.  
  382. void PR_ClearGrabMacros (void);
  383.  
  384. boolean    PR_CompileFile (char *string, char *filename);
  385.  
  386. extern    boolean    pr_dumpasm;
  387.  
  388. extern    string_t    s_file;            // filename for function definition
  389.  
  390. extern    def_t    def_ret, def_parms[MAX_PARMS];
  391.  
  392. //=============================================================================
  393.  
  394. #define    MAX_STRINGS        500000
  395. #define    MAX_GLOBALS        16384
  396. #define    MAX_FIELDS        1024
  397. #define    MAX_STATEMENTS    65536
  398. #define    MAX_FUNCTIONS    8192
  399.  
  400. #define    MAX_SOUNDS        1024
  401. #define    MAX_MODELS        1024
  402. #define    MAX_FILES        1024
  403. #define    MAX_DATA_PATH    64
  404.  
  405. extern    char    strings[MAX_STRINGS];
  406. extern    int        strofs;
  407.  
  408. extern    dstatement_t    statements[MAX_STATEMENTS];
  409. extern    int            numstatements;
  410. extern    int            statement_linenums[MAX_STATEMENTS];
  411.  
  412. extern    dfunction_t    functions[MAX_FUNCTIONS];
  413. extern    int            numfunctions;
  414.  
  415. extern    float        pr_globals[MAX_REGS];
  416. extern    int            numpr_globals;
  417.  
  418. extern    char    pr_immediate_string[2048];
  419.  
  420. extern    char        precache_sounds[MAX_SOUNDS][MAX_DATA_PATH];
  421. extern    int            precache_sounds_block[MAX_SOUNDS];
  422. extern    int            numsounds;
  423.  
  424. extern    char        precache_models[MAX_MODELS][MAX_DATA_PATH];
  425. extern    int            precache_models_block[MAX_SOUNDS];
  426. extern    int            nummodels;
  427.  
  428. extern    char        precache_files[MAX_FILES][MAX_DATA_PATH];
  429. extern    int            precache_files_block[MAX_SOUNDS];
  430. extern    int            numfiles;
  431.  
  432. int    CopyString (char *str);
  433.  
  434.  
  435.